home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
500 MB Nyheder Direkte fra Internet 2
/
500 MB nyheder direkte fra internet CD 2.iso
/
start
/
data
/
text
/
weird.txt
< prev
next >
Wrap
Text File
|
1994-09-21
|
68KB
|
1,548 lines
FANCY INPUT
The typical INPUT statement looks like this:
10 INPUT "WHAT IS YOUR NAME";N$
It makes the computer ask ``WHAT IS YOUR NAME?'' then wait for
you to answer to question. So when you run the program, the
conversation looks like this:
WHAT IS YOUR NAME? MARIA
Notice that the computer automatically adds a question mark at
the end of the question, and leaves a blank space after the
question mark.
Omitting the question mark
If you want to omit the question mark and the blank space,
replace the semicolon by a comma:
10 INPUT "WHAT IS YOUR NAME",N$
The computer will omit the question mark and the blank space, so
the conversation will look like this:
WHAT IS YOUR NAMEMARIA
Here's a prettier example of how to use the comma:
10 INPUT "PLEASE TYPE YOUR NAME...",N$
The conversation will look like this:
PLEASE TYPE YOUR NAME...MARIA
Here's an even prettier example:
10 INPUT "TO BECOME A MOVIE STAR, TYPE YOUR NAME NEXT TO THE
STARS***";N$
The conversation will look like this:
TO BECOME A MOVIE STAR, TYPE YOUR NAME NEXT TO THE STARS***MARIA
Omitting the prompt
The typical INPUT statement contains a question, such as ``WHAT
IS YOUR NAME''. The question is called the prompt. If you wish,
you can omit the prompt, like this:
10 INPUT N$
That line doesn't include a question, but the computer still
prints a question mark followed by a blank space, so the
conversation looks like this:
? MARIA
To make that example more practical, add a PRINT statement
above line 10, like this:
9 PRINT "PLEASE TYPE YOUR NAME AFTER THE QUESTION MARK"
10 INPUT N$
That makes the conversation look like this:
PLEASE TYPE YOUR NAME AFTER THE QUESTION MARK
? MARIA
Adjacent printing
Here's a simple program:
10 INPUT "WHAT IS YOUR NAME";N$
20 PRINT "!!!WHAT A WONDERFUL NAME!!!"
It produces this conversation:
WHAT IS YOUR NAME? MARIA
!!!WHAT A WONDERFUL NAME!!!
To have more fun, insert a semicolon immediately after the word
INPUT, like this:
10 INPUT;"WHAT IS YOUR NAME";N$
20 PRINT "!!!WHAT A WONDERFUL NAME!!!"
The conversation will begin normally:
WHAT IS YOUR NAME? MARIA
But when you press the ENTER key after MARY, the extra semicolon
makes the computer print line 20 next to MARIA, like this:
WHAT IS YOUR NAME? MARIA!!!WHAT A WONDERFUL NAME!!!
To surprise your friends, run this program:
10 INPUT;"WHAT IS YOUR NAME";N$
20 PRINT N$;N$;N$
The program begins by asking:
WHAT IS YOUR NAME?
Suppose the person says MARIA, like this:
WHAT IS YOUR NAME? MARIA
When the person presses the ENTER key after MARIA, line 20
automatically prints MARIA three more times afterwards, like
this:
WHAT IS YOUR NAME? MARIAMARIAMARIAMARIA
This program asks for your first name, then your last name:
10 INPUT;"WHAT IS YOUR FIRST NAME";F$
20 INPUT " WHAT IS YOUR LAST NAME";L$
Line 10 makes the conversation begin like this:
WHAT IS YOUR FIRST NAME? MARIA
When you press the ENTER key after MARIA, the extra semicolon in
line 10 makes line 20 appear on the same line, like this:
WHAT IS YOUR FIRST NAME? MARIA WHAT IS YOUR LAST NAME?
If you answer WONG, the whole conversation looks like this:
WHAT IS YOUR FIRST NAME? MARIA WHAT IS YOUR LAST NAME? YEE
Multiple input
This program asks for your name, age, and weight:
10 INPUT "NAME, AGE, WEIGHT";N$,A,W
When you run the program, the computer asks:
NAME, AGE, WEIGHT?
The computer waits for you to type your name, age, and weight.
When you type them, put commas between them, like this:
NAME, AGE, WEIGHT? JOHN,25,148
If your name is ``JOHN SMITH, JR.'', and you want to input all
that instead of just JOHN, you must put quotation marks around
your name:
NAME, AGE, WEIGHT? "JOHN SMITH, JR.",25,148
Here's the rule: you must put quotation marks around any INPUT
string that contains a comma.
LINE INPUT
If you say ___
10 LINE INPUT "PLEASE TYPE YOUR NAME...";N$
the computer will say:
PLEASE TYPE YOUR NAME...
Then the computer will wait for you to type your name. You do not
have to put quotation marks around your name, even if your name
contains a comma. LINE INPUT means: the entire line that the
person inputs will become the string, even if the line contains a
comma.
Notice that the LINE
INPUT statement does not make the computer automatically print a
question mark. And notice that the variable must be a string
(such as N$), not a number.
INPUT$
This program reveals
private information about MARY:
10 PRINT "MARY SECRETLY WISHES TO KISS A COW"
Here's how to protect
that program, so only people who know the ``secret password'' can
run it. . . .
First, invent a secret
password. Let's make it be ``TUNA''.
Here's the program:
5 INPUT "WHAT'S THE SECRET PASSWORD";P$
10 IF P$="TUNA" THEN PRINT "MARY SECRETLY WISHES TO KISS A C
OW" ELSE PRINT "YOU ARE AN UNAUTHORIZED USER"
Line 5 asks the person to type the secret password. Whatever the
person types is called P$. If the person types TUNA, line 10
makes the computer say:
MARY SECRETLY WISHES TO KISS A COW
But if the person does not type TUNA, the computer says ``YOU ARE
AN UNAUTHORIZED USER'' and refuses to reveal Mary's secret
desire.
This program's better:
5 PRINT "PLEASE TYPE THE SECRET PASSWORD"
6 P$=INPUT$(4)
10 IF P$="TUNA" THEN PRINT "MARY SECRETLY WISHES TO KISS A C
OW" ELSE PRINT "YOU ARE AN UNAUTHORIZED USER"
Line 5 makes the computer say:
PLEASE TYPE THE SECRET PASSWORD
Line 6 waits for the person to input 4 characters. The characters
that the person inputs will become P$. For example, suppose the
person types T, then U, then N, then A; then P$ will become TUNA
and the computer will reveal Mary's secret.
While the person inputs
the 4 characters, they won't appear on the screen; they'll be
invisible. That's to prevent other people in the room from
peeking at the screen and noticing the password.
After typing the 4
characters, the person does not have to press the ENTER key. As
soon as the person types the 4th character, the computer makes P$
be the 4 characters that the person typed.
Broken computer This devilish program makes your computer
pretend to be broken, so that whenever you press the W key your
screen shows an F instead:
10 CLS
20 A$=INPUT$(1)
30 IF A$="W" THEN PRINT "F"; ELSE PRINT A$;
40 GO TO 20
Line 10 clears the screen (makes the screen go blank), so that
your friends don't see the program. Line 20 waits for you to type
1 character. Line 30 says: if the character you typed was W,
print an F on the screen instead; otherwise, print the character
you typed. Line 40 makes the routine repeat, forever. For
example, if you try to type ``THE WEATHER IS WONDERFUL'', you'll
see this on the screen instead:
THE FEATHER IS FONDERFUL
For an even wilder time, tell the computer to change each ``E''
to ``OOGA'', by changing line 30 to this:
30 IF A$="E" THEN PRINT "OOGA"; ELSE PRINT A$;
Then if you try to type ``WE ARE HERE'', you'll see this on the
screen instead:
WOOGA AROOGA HOOGAROOGA
Abridged literature This program gives you a choice of
literature:
10 PRINT "WELCOME TO THE WORLD'S GREAT LITERATURE, ABRIDGED"
20 PRINT "WHICH KIND OF LITERATURE WOULD YOU LIKE?"
30 PRINT "N: NOVEL"
40 PRINT "P: POEM"
50 PRINT "PLEASE PRESS N OR P"
60 A$=INPUT$(1)
70 IF A$="N" THEN GO TO 100
80 IF A$="P" THEN GO TO 200
90 GO TO 50
100 PRINT "HE: I LOVE YOU"
110 PRINT "SHE: I'M PREGNANT"
120 PRINT "HE: LET'S GET MARRIED"
130 PRINT "SHE: LET'S GET DIVORCED"
140 PRINT "HE: LET'S GET BACK TOGETHER"
150 PRINT "SHE: TOO BAD YOU DIED IN THE WAR, BUT I'LL NEVER
FORGET YOU!"
160 END
200 PRINT "NOSES"
210 PRINT "BLOWSES"
Lines 10-50 make the computer print:
WELCOME TO THE WORLD'S GREAT LITERATURE, ABRIDGED
WHICH KIND OF LITERATURE WOULD YOU LIKE?
N: NOVEL
P: POEM
PLEASE PRESS N OR P
Line 60 makes the computer wait for you to press a key. You do
not have to press the ENTER key afterwards.
If you press the N key, line 70 sends the computer to line 100,
which prints an abridged novel. If you press the P key instead,
line 80 sends the computer to line 200, which prints an abridged
poem.
If you press neither N nor P, the computer arrives at line 90,
which sends the computer back to line 50, which reminds you to
press N or P.
JOYSTICK VERSUS MOUSE
Instead of using the
keyboard, you can input by using a joystick or mouse.
Joystick
A joystick is a stick
that sticks up from a box. You can wiggle the stick in all four
directions (left, right, forward, and back) and diagonally.
In line 100 of your
program, if you want the computer to look at the joystick, say:
100 X=STICK(0): Y=STICK(1)
That line makes X become a number that indicates how far the
joystick is being pulled to the right, and Y become a number that
indicates how far the joystick is being pushed forward. To make
the computer print X and Y on your screen, say:
110 PRINT X,Y
To make the computer
look at the joystick again and again, repeatedly, create a loop,
by adding this line:
120 GO TO 100
Then as you wiggle the joystick, you can watch the numbers on the
screen change.
Besides printing the
numbers X and Y on the screen, you can use the numbers X and Y in
graphics statements (such as PLOT, LINE, and CIRCLE), so that the
joystick controls the location of graphics shapes on the screen.
You can also use the X and Y numbers in the SOUND statement, so
that the joystick controls the pitch of musical sounds: moving
the joystick will change the pitch.
Mouse
A mouse is a small box
about the size of a pack of cigarettes. You can slide the mouse
across your desk in all four directions (left, right, forward,
and back) and diagonally.
Some versions of BASIC
let your program contain commands to handle a mouse. Those
commands are called mouse commands.
(GWBASIC and QBASIC do
not let programs contain mouse commands. If you're using GWBASIC
or QBASIC, skip ahead to the next page.)
If your computer's BASIC
understands mouse commands, and you want the computer to look at
the mouse in line 100 of your program, say this:
100 M=MOUSE(0): X=MOUSE(1): Y=MOUSE(2)
In that line, the ``M=MOUSE(0)'' makes the computer look at the
mouse. The rest of the line makes X become a number that
indicates how far the mouse was moved to the right, and Y become
a number that indicates how far the mouse was moved forward. To
make the computer print X and Y on your screen, say:
110 PRINT X,Y
To make the computer
look at the mouse again and again repeatedly, create a loop by
adding this line:
120 GO TO 100
Then as you move the mouse across your desk, you can watch the
numbers on the screen change.
SWAP
Modern computers understand the word SWAP:
10 A=4: B=9
20 SWAP A,B
30 PRINT A;B
Line 10 says A is 4 and B is 9. Line 20 swaps A with B, so that
A becomes 9, and B becomes 4. Line 30 prints:
9 4
If your computer is old-fashioned and doesn't understand the
word SWAP, replace line 20 by this:
20 S=A: A=B: B=S
That example swapped numbers. You can also swap strings:
10 A$="HORSE": B$="CART"
20 SWAP A$,B$
30 PRINT A$;" ";B$
Line 10 says A$ is ``HORSE'' and B$ is ``CART''. Line 20 swaps A$
with B$, so that A$ becomes ``CART'', and B$ becomes ``HORSE''.
Line 30 puts the CART before the HORSE:
CART HORSE
If your computer doesn't understand SWAP, replace line 20 by
this:
20 S$=A$: A$=B$: B$=S$
Don't forget the dollar signs!
Shuffling
Here are some cards:
Queen of Hearts
Jack of Diamonds
Ace of Spades
Joker
King of Clubs
Let's shuffle them, to put them into
a random order.
To begin, put the list of cards into
a DATA statement:
10 DATA QUEEN OF HEARTS,JACK OF DIAMONDS,ACE OF SPADES,JOKER,KING
OF CLUBS
We have 5 cards:
20 N=5
Let the Queen of Hearts be called
X$(1), the Jack of Diamonds be called X$(2), the Ace of Spades be
called X$(3), the Joker be called X$(4),and the King of Clubs be
called X$(5):
30 DIM X$(N)
40 FOR I = 1 TO N: READ X$(I): NEXT
Shuffle the cards, by using the
following strategy. . . .
Swap the card N with a random card
before it (or with itself); then swap card N-1 with a random card
before it (or with itself); then swap card N-2 with a random card
before it (or with itself); etc. Keep doing that, until you
finally reach card 2, which you swap with a random card before it
(or with itself). Here's the code:
50 RANDOMIZE
60 FOR I = N TO 2 STEP -1: SWAP X$(I),X$(RND(I)): NEXT
If your computer doesn't understand SWAP, replace ``SWAP
X$(I),X$(RND(I))'' by this:
R=RND(I): S$=X$(I): X$(I)=X$(R): X$(R)=S$
If your computer doesn't understand the word RANDOMIZE, or
doesn't understand that RND(I) is a random number from 1 to I,
you must make further changes.
Finally, print the shuffled deck:
70 FOR I = 1 TO N: PRINT X$(I): NEXT
The computer will print something
like this:
KING OF CLUBS
JOKER
JACK OF DIAMONDS
QUEEN OF HEARTS
ACE OF SPADES
To shuffle a larger deck, change
just lines 10 and 20.
Sorting
Putting words in alphabetical order ___ or putting numbers in
numerical order ___ is called sorting.
Short Three-Line Sort Here are a dozen names: Sue, Ann, Joe,
Alice, Ted, Jill, Fred, Al, Sam, Pat, Sally, Moe. Let's make the
computer alphabetize them (sort them).
To begin, put the list of names into a DATA statement:
10 DATA SUE,ANN,JOE,ALICE,TED,JILL,FRED,AL,SAM,PAT,SALLY,MOE
We have 12 names:
20 N=12
Let Sue be called X$(1), Ann be called X$(2), Joe be called
X$(3), etc. Here's how:
30 DIM X$(N)
40 FOR I = 1 TO N: READ X$(I): NEXT
Alphabetize the names, by using the following strategy. . . .
Compare the first name against the second; if they're not in
alphabetical order, swap them. Compare the second name against
the third; if they're not in alphabetical order, swap them.
Compare the third name against the fourth; if they're not in
alphabetical order, swap them. Continue that process, until you
finally compare the last two names. But each time you swap, you
must start the whole process over again, to make sure the
preceding names are still in alphabetical order. Here's the code:
50 FOR I = 1 TO N-1
60 IF X$(I)>X$(I+1) THEN SWAP X$(I),X$(I+1): GO TO 50
70 NEXT
Finally, print the alphabetized list:
80 FOR I = 1 TO N: PRINT X$(I): NEXT
The computer will print:
AL
ALICE
ANN
FRED
JILL
JOE
MOE
PAT
SALLY
SAM
SUE
TED
In that program, the sorting occurs in lines 50-70. Those three
short lines are called the Short Three-Line Sort.
Those three lines form a loop. The part of the loop that the
computer encounters the most often is the phrase ``IF
X$(I)>X$(I+1)''. In fact, if you tell the computer to alphabetize
a list of names that's long (several hundred names), the computer
spends the majority of its time repeatedly handling ``IF
X$(I)>X$(I+1)''.
How long will the computer take to handle a long list of names?
The length of time depends mainly on how often the computer
encounters the phrase ``IF X$(I)>X$(I+1)''.
If the list contains N names, the number of times that the
computer encounters the phrase ``IF X$(I)>X$(I+1)'' is
approximately N3/8. Here are some examples:
N (number of names)N3/8 (approximate number of encounters)
10 125
12 216
20 1,000
40 8,000
100 125,000
1,000 125,000,000
10,000 125,000,000,000
For example, the chart says that a list of 12 names requires
approximately 216 encounters.
The 216 is
just an approximation: the exact number of encounters depends on
which list of names you're trying to alphabetize. If the list is
nearly in alphabetical order already, the number of encounters
will be less than 216; if the list is in reverse alphabetical
order, the number of encounters will be more than 216; but if the
list is typical (not yet in any particular order), the number of
encounters will be about 216. For the list that we tried (Sue,
Ann, Joe, Alice, Ted, Jill, Fred, Al, Sam, Pat, Sally, Moe), the
exact number of encounters happens to be 189, which is close to
216.
How long will your computer take to finish sorting? The length
of time depends on which computer you have, how many names are in
the list, and how long each name is. A typical microcomputer
(handling a list of typical names) requires .01 seconds per
encounter. Multiplying the number of encounters by .01 seconds,
you get:
Number of namesEncounters (N3/8) Time
10 125 1.25 secs
12 216 2.16 secs
20 1,000 10 secs
40 8,000 80 secs = 1.3 minutes
100 125,000 1,250 secs = 20.8 minutes
1,000 125,000,000 1,250,000 secs = 14.4 days
10,000 125,000,000,0001,250,000,000 secs = 39.6 years
Moral: never let a 70-year-old programmer alphabetize a list of
10,000 names by using the Short Three-Line Sort ___ because when
the computer finishes running the program (39.6 years later), the
programmer will probably be dead!
Fancy Three-Line Sort In the Short Three-Line Sort, the end of
line 60 says ``GO TO 50''. For an interesting experiment, replace
the ``GO TO 50'' by ``IF I>1 THEN I=I-1: GO TO 60'', so that line
60 looks like this:
60 IF X$(I)>X$(I+1) THEN SWAP X$(I),X$(I+1): IF I>1 THEN
I=I-1: GO TO 60
Even though that new, fancy version of line 60 is longer to
type than the original, the computer handles it more quickly,
because it tells the computer to GO TO line 60 instead of forcing
the computer to go all the way back to line 50. The fancy version
is called the Fancy Three-Line Sort.
If you feed the computer the Fancy Three-Line Sort (instead of
the Short Three-Line Sort), the computer encounters the ``IF
X$(I)>X$(I+1)'' less often: just N2/2 times (instead of N3/8).
Number of namesEncounters (N2/2) Time
10 50 .50 secs
12 72 .72 secs
20 200 2 secs
40 800 8 secs
100 5,000 50 secs
1,000 500,000 5,000 secs = 1.4 hours
10,000 50,000,000 500,000 secs = 5.8 days
Now you can hire the 70-year old programmer: to alphabetize
10,000 names, he'll need just 5.8 days instead of 39.6 years. By
changing just the end of line 60, we saved almost 40 years of
computer time ___ and the programmer's job!
Super-Fancy Three-Line Sort To reduce the time even further,
use the Super-Fancy Three-Line Sort instead, which is:
50 FOR I = 1 TO N-1
60 FOR J = I TO 1 STEP -1: IF X$(J)>X$(J+1) THEN SWAP
X$(J),X$(J+1): NEXT
70 NEXT I
When typing the Super-Fancy Three-Line Sort, make sure you type
line 60 correctly: you must put the IF on the same line as the
NEXT. In line 70, make sure you put the ``I'' after NEXT;
otherwise, the computer might think you mean NEXT J.
For the Super-Fancy Three-Line Sort, the number of times the
computer encounters the phrase ``IF X$(J)>X$(J+1)'' is just N2/4:
Number of namesEncounters (N2/4) Time
10 25 .25 secs
12 36 .36 secs
20 100 1 secs
40 400 4 secs
100 2,500 25 secs
1,000 250,000 2,500 secs = 41.7 minutes
10,000 25,000,000 250,000 secs = 2.9 days
Six-Line Sort The Six-Line Sort reduces the time even further.
To construct the Six-Line Sort, begin with the Super-Fancy
Three-Line Sort, but change each +1 to +D, and change each -1 to
-D, so that you get:
50 FOR I = 1 TO N-D
60 FOR J = I TO 1 STEP -D: IF X$(J)>X$(J+D) THEN SWAP
X$(J),X$(J+D): NEXT
70 NEXT I
D begins by
being N ___
42 D=N
but then decreases, so that it becomes a fifth of its original
value:
44 D=INT(D/5)+1
After performing lines 50-70 for that D, check whether D is down
to 1 yet; if it isn't, repeat the process:
75 IF D>1 THEN GO TO 44
So altogether, the complete Six-Line Sort looks like this:
42 D=N
44 D=INT(D/5)+1
50 FOR I = 1 TO N-D
60 FOR J = I TO 1 STEP -D: IF X$(J)>X$(J+D) THEN SWAP
X$(J),X$(J+D): NEXT
70 NEXT I
75 IF D>1 THEN GO TO 44
For the Six-Line Sort, the number of times the computer
encounters the phrase ``IF X$(J)>X$(J+D)'' is just
1.5*(N-1)^(4/3):
Number of namesEncounters Time
10 28 .28 secs
12 37 .37 secs
20 76 .76 secs
40 198 1.98 secs
100 687 6.87 secs
1,000 14,980 149.80 secs = 2.5 minutes
10,000 323,122 3,231.22 secs = 53.9 minutes
Notice that the Six-Line Sort handles 10,000 names in 53.9
minutes. That's much faster than the Super-Fancy Three-Line Sort,
which takes 2.9 days. But to handle just 10 names, the Six-Line
Sort does not run faster than the Super-Fancy Three-Line Sort. So
use the Six-Line Sort just for handling long lists of names.
To make the Six-Line Sort even faster, add this line:
1 DEFINT A-Z
That tells the computer that none of the variables stands for a
decimal. By saying DEFINT A-Z, you enable the computer to run the
program 20% faster, so that the timing looks like this:
Number of names Time
10 .2 secs
12 .3 secs
20 .6 secs
40 1.6 secs
100 5.5 secs
1,000 120 secs = 2 minutes
10,000 2,580 secs = 43 minutes
We've sure come a long way! Our first attempt (the Short
Three-Line Sort) took 39.6 years to alphabetize 10,000 names; our
newest attempt (the Six-Line Sort with DEFINT) takes just 43
minutes.
If you try running those sorting methods on your computer,
you'll find the timings are slightly different, since the exact
timings depend on which computer you have, the length of each
name, and how badly the names are out of order.
Famous sorts Although I ``invented'' all those sorting methods,
most of them are just slight improvements on methods that were
developed by others. For example, the Super-Fancy Three-Line Sort
is a slight improvement on the Shuttle Sort, which was invented
by Shaw & Trimble in 1983. The Six-Line Sort is a slight
improvement on the Shell Sort, which was invented by Donald Shell
in 1959 and further developed by Hibbard & Boothroyd in 1963,
Peterson & Russell in 1971, and Knuth in 1973.
Phone directory Suppose you want to alphabetize this phone
directory:
Name Phone number
Mary Smith277-8139
John Doe513-9134
Russ Walter666-2666
Information555-1212
Just use one of the alphabetizing programs I showed you! Type
the DATA like this:
10 DATA SMITH MARY 277-8139,DOE JOHN 513-9134
20 DATA WALTER RUSS 666-2666,INFORMATION 555-1212
The computer will print:
DOE JOHN 513-9134
INFORMATION 555-1212
SMITH MARY 277-8139
WALTER RUSS 666-2666
Sorting
numbers Suppose you want to put a list of numbers into increasing
order. For example, if the numbers are 51, 4.257, -814, 62, and
.2, let's make the computer print:
-814
.2
4.257
51
62
To do that,
just use one of the alphabetizing programs I showed you ___ but
in the DATA statement, put the numbers instead of strings; and
remove the dollar signs (say X instead of X$).
To put a
list of numbers into decreasing order, begin by writing a program
that puts them into increasing order, and then change line 60
from ``>X'' to ``<X''.
ON
The computer understands the word ``ON''.
ON . . . GO TO
In your program, you can say:
50 ON N GO TO 80,100,20,350
That means: go to either 80, 100, 20, or 350; the decision
depends on what N is. In other words:
If N is 1, go to 80.
If N is 2, go to 100.
If N is 3, go to 20.
If N is 4, go to 350.
In that example, if N is not 1, 2, 3, or 4, the computer will
not go to line 80 or 100 or 20 or 350; instead, the computer will
proceed to the line underneath line 50 (which is probably line
60).
Exception: if N is greater than 255 or a negative number (such
as -1), the computer thinks you're crazy, and so the computer
gripes at you instead of proceeding to line 60.
Another exception: if N is a decimal (such as 3.1), the
computer treats N as if it were a whole number (3); so in that
example, if N is 3.1, the computer will go to line 20.
Christmas Remember the Christmas
carol called ``The Twelve Days of Christmas''? The first three
verses go like this:
ON THE FIRST DAY OF CHRISTMAS, MY TRUE LOVE SENT TO ME
A PARTRIDGE IN A PEAR TREE.
ON THE SECOND DAY OF CHRISTMAS, MY TRUE LOVE SENT TO ME
TWO TURTLE DOVES...AND
A PARTRIDGE IN A PEAR TREE.
ON THE THIRD DAY OF CHRISTMAS, MY TRUE LOVE SENT TO ME
THREE FRENCH HENS,
TWO TURTLE DOVES...AND
A PARTRIDGE IN A PEAR TREE.
This program prints the final verse:
10 PRINT "ON THE TWELFTH DAY OF CHRISTMAS, MY TRUE LOVE SENT TO
ME"
20 PRINT "TWELVE DRUMMERS DRUMMING,"
30 PRINT "ELEVEN PIPERS PIPING,"
40 PRINT "TEN LORDS A-LEAPING,"
50 PRINT "NINE LADIES DANCING,"
60 PRINT "EIGHT MAIDS A-MILKING,"
70 PRINT "SEVEN SWANS A-SWIMMING,"
80 PRINT "SIX GEESE A-LAYING,"
90 PRINT "FIVE GO---OLD RINGS,"
100 PRINT "FOUR CALLING BIRDS,"
110 PRINT "THREE FRENCH HENS,"
120 PRINT "TWO TURTLE DOVES...AND"
130 PRINT "A PARTRIDGE IN A PEAR TREE."
This program prints all twelve
verses:
1 DATA FIRST,SECOND,THIRD,FOURTH,FIFTH,SIXTH,SEVENTH,EIGHTH,NINTH
2 DATA TENTH,ELEVENTH,TWELFTH
3 FOR V = 1 TO 12
4 READ W$
10 PRINT "ON THE ";W$;" DAY OF CHRISTMAS, MY TRUE LOVE SENT
TO ME"
11 ON V GO TO 130,120,110,100,90,80,70,60,50,40,30,20
20 PRINT "TWELVE DRUMMERS DRUMMING,"
30 PRINT "ELEVEN PIPERS PIPING,"
40 PRINT "TEN LORDS A-LEAPING,"
50 PRINT "NINE LADIES DANCING,"
60 PRINT "EIGHT MAIDS A-MILKING,"
70 PRINT "SEVEN SWANS A-SWIMMING,"
80 PRINT "SIX GEESE A-LAYING,"
90 PRINT "FIVE GO---OLD RINGS,"
100 PRINT "FOUR CALLING BIRDS,"
110 PRINT "THREE FRENCH HENS,"
120 PRINT "TWO TURTLE DOVES...AND"
130 PRINT "A PARTRIDGE IN A PEAR TREE."
140 PRINT
150 NEXT
Lines 1 and 2 teach the computer how
to spell the words ``FIRST'', ``SECOND'', ``THIRD'', etc. Line 3
makes the computer do lines 4 through 140, twelve times (once for
each verse). Lines 4 and 10 look at the data and print the top
line of the verse. Line 11 says:
If V is 1, go to line 130 (so the computer prints A PARTRIDGE IN
A PEAR TREE).
If V is 2, go to line 120 (so the computer prints TWO TURTLE
DOVES...AND A PARTRIDGE IN A PEAR TREE).
If V is 3, go to line 110 (so the computer prints THREE FRENCH
HENS, TWO TURTLE DOVES...AND A PARTRIDGE IN A PEAR TREE).
And so on, for each verse.
ON . . . GOSUB
You can say:
50 ON N GOSUB 80,100,20,350
That means:
If N is 1, GOSUB 80.
If N is 2, GOSUB 100.
If N is 3, GOSUB 20.
If N is 4, GOSUB 350.
ON ERROR GO TO
If the computer finds an error while running your program, the
computer wants to gripe. But instead of letting the computer
gripe, you can force the computer to do something different.
For example, you can tell the computer, ``If you find an error
in lines 50-70, don't gripe; instead of griping, do the special
routine that begins at line 1000.'' To tell the computer that,
insert these lines:
49 ON ERROR GO TO 1000
71 ON ERROR GO TO 0
Lines 49 and 71 tell the computer, ``If you find an error between
lines 49 and 71, go to the special routine that begins at line
1000.''
Invent your own special routine, so that it begins at line 1000
and continues onto lines 1010, 1020, etc.
The bottom line of your special routine should tell the
computer where to go afterwards.
For example, suppose that after the routine is done, you want
the computer to go back to line 30 (to try again). Just put this
line at the bottom of the routine:
1090 RESUME 30
That way, if an error occurs between lines 49 and 71, the
computer will do the routine in lines 1000-1080, then come to
line 1090, which sends the computer back to line 30.
The special routine (in lines 1000-1090) is called an
error-handling routine or an error trap. Its bottom line says
RESUME. (By contrast, the bottom line of an ordinary subroutine
says RETURN instead.)
To separate the main routine (lines 10-999) from the
error-handing routine (lines 1000-1090), the bottom line of the
main routine should say END, like this:
999 END
Instead of saying RESUME 30, which sends the computer back to
line 30, you can send the computer back to any other line you
wish. For example, you can say RESUME 80.
If you don't put any number after RESUME, the computer will go
back to the line that contained the error.
If you say RESUME NEXT, the computer will go to the line
underneath the line that contained the error. To make RESUME NEXT
work properly, the line that contained the error should consists
of just one statement (instead of statements separated by
colons).
MEMORY CELLS
The computer's main memory consists
of many memory cells. Each cell holds an integer from 0 to 255.
For example, cell #7512 might hold the integer 17.
PEEK
To find out what number's in cell
#7512, say:
PRINT PEEK(7512)
That makes the computer peek at cell #7512, find the number in
that cell, and print that number on your screen. The number it
prints will be an integer from 0 to 255. For example, it might be
17.
POKE
The memory contains two kinds of
cells. One kind, called ROM, contains information permanently.
The other kind, called RAM, contains information temporarily, and
you can change that information. When you turn the computer on,
each RAM cell contains a 0, but you can change the zeros to other
numbers.
If you say ___
POKE 7512,14
the computer will try to put the number 14 into cell #7512. If
cell #7512 is in the RAM, the computer will succeed. If cell
#7512 is in the ROM, the computer will give up, since the
information in ROM cells is permanent and can't be changed.
To find out whether the computer
successfully put the number 14 into cell #7512, say:
PRINT PEEK(7512)
If the computer prints 14, the computer successfully poked. If
the computer prints a different number instead, the computer's
POKE was unsuccessful, which means cell #7512 is in the ROM and
therefore can't be changed.
When you turn the computer on, the
ROM cells contain their permanent information, but the RAM cells
are ``blank''; each RAM cell contains 0. To change the numbers in
the RAM cells, say POKE.
How RAM is used
Whenever you type a new program or
command or data, the computer temporarily stores what you typed
in the RAM.
For example, if you type the word
CAB (because you're writing a program about taxicabs), the
computer temporarily puts the ASCII code numbers for C, A, and B
into RAM cells. Since C's ASCII code number is 67, A's is 65, and
B's is 66, the computer puts the numbers 67, 65, and 66 into
three RAM cells.
As you type more programs, commands,
and data, the computer puts their ASCII code numbers into RAM
cells. Into other RAM cells, the computer puts notes about what
you and the computer are doing.
If you say to POKE a number into a
RAM cell, beware: the computer might already be using that cell
to hold an important note. The number you POKE into the cell will
replace the computer's note. The computer will forget the note,
get confused, and go crazy. If the RAM cell contained a note
about your program, the computer might wreck your program; if the
RAM cell contained a note about the disk drive, the computer
might go so crazy that it will turn the drive on and wreck all
the information on the disk!
So before you say POKE, find out
which RAM cells the computer uses for which purposes ___ and as
an extra precaution, remove your disk from the drive. Don't
reinsert the disk until you've turned off the computer and
started fresh again.
SEQUENTIAL DATA FILES
Here's a simple program:
10 PRINT "EAT"
20 PRINT 2+2
30 PRINT "EGGS"
It makes the computer print this message onto your screen:
EAT
4
EGGS
Instead of printing that message onto your screen, let's make
the computer print the message onto your disk. Here's how. . . .
OPEN FOR OUTPUT
This program prints the message onto your disk, instead of onto
your screen:
5 OPEN "SUE" FOR OUTPUT AS 1
10 PRINT#1, "EAT"
20 PRINT#1, 2+2
30 PRINT#1, "EGGS"
40 CLOSE
Lines 10-30 make the computer print the message onto your disk,
instead of onto your screen. Each line says PRINT#1, which means:
print onto the disk.
Line 5 is an introductory line that tells the computer where on
the disk to print the message. Line 5 says: find a blank place on
the disk, call it ``SUE'', and make ``SUE'' be file#1. So
PRINT#1, will mean: print onto file#1, which is SUE.
Any program that says OPEN should also say CLOSE, so line 40
says CLOSE. The CLOSE line makes the computer put some
``finishing touches'' on SUE, so that SUE becomes a perfect,
finished file.
When you RUN that program, the computer will automatically put
onto the disk a file called ``SUE'' that contains this message:
EAT
4
EGGS
After running the program, if you want to see the names of all
the files on the disk, type FILES (or DIRECTORY or CATALOG or
whatever other word your computer uses). The computer will print
the names of all the files ___ and one of the names it prints
will be SUE.
OPEN FOR INPUT
To see the message
that's in SUE, run this program, which inputs from SUE and prints
onto your screen:
5 OPEN "SUE" FOR INPUT AS 1
10 INPUT#1, A$
11 PRINT A$
20 INPUT#1, B
21 PRINT B
30 INPUT#1, C$
31 PRINT C$
40 CLOSE
Line 5 prepares the
computer to input from SUE.
Line 10 inputs A$ from
SUE, so A$ is EAT. Line 11 prints EAT onto your screen.
Line 20 inputs B from
SUE, so B is 4. Line 21 prints 4 onto your screen.
Line 30 inputs C$ from
SUE, so C$ is EGGS. Line 31 prints EGGS onto your screen. So
altogether, on your screen you'll see:
EAT
4
EGGS
Line 40 tells the
computer that you're done using SUE for a while (until you say
OPEN again).
OPEN FOR APPEND
After you've put SUE
onto the disk, so that SUE consists of EAT and 4 and EGGS, try
running this program:
10 OPEN "SUE" FOR APPEND AS 1
20 PRINT#1, "GOOD MORNING!"
30 CLOSE
In line 10, the word
APPEND tells the computer to keep adding onto SUE. So when the
computer comes to line 20, it adds ``GOOD MORNING'' onto SUE, and
SUE becomes this:
EAT
4
EGGS
GOOD MORNING!
Erasing
For your next
experiment, try running this program:
10 OPEN "SUE" FOR OUTPUT AS 1
20 PRINT#1, "PICKLES ARE PLEASANT"
30 CLOSE
Since line 10 does not
say APPEND, the computer will not keep adding onto SUE. Instead,
the computer erases everything that's been in SUE. So when the
computer finishes processing line 10, SUE's become blank.
Line 20 puts ``PICKLES
ARE PLEASANT'' into SUE. So at the end of the program, SUE
includes ``PICKLES ARE PLEASANT''; but SUE does not include EAT
and 4 and EGGS and ``GOOD MORNING'', which have all been erased.
Loops
This program lets you put the names of all your friends onto
the disk:
10 OPEN "FRIENDS" FOR OUTPUT AS 1
20 PRINT "PLEASE TYPE A FRIEND'S NAME (OR THE WORD 'END')"
30 INPUT F$: IF F$="END" THEN CLOSE: END
40 PRINT#1, F$
50 GO TO 20
Line 10 makes the computer find a blank space on the disk and
call it FRIENDS. Line 20 makes the computer print:
PLEASE TYPE A FRIEND'S NAME (OR THE WORD 'END')
Line 30 prints a question mark and waits for you to type
something; whatever you type will be called F$. For example, if
you type JOAN WILLIAMS, then F$ will be JOAN WILLIAMS, and line
40 prints the name JOAN WILLIAMS onto the disk.
Line 50 creates a loop, so that you can type as many names as
you wish. (Remember to press the ENTER key after each name.)
When you've finished typing the names of all your friends, type
the word END. Then the last part of line 30 will make the
computer CLOSE the file and END the program.
This program makes the computer look at the FRIENDS file and
copy all its names to your screen:
10 OPEN "FRIENDS" FOR INPUT AS 1
20 IF EOF(1) THEN PRINT "THOSE ARE ALL THE FRIENDS": CLOSE: END
30 INPUT#1, F$
40 PRINT F$
50 GO TO 20
Line 10 prepares the computer to input from the FRIENDS file.
Line 20 is special; I'll explain it later. Line 30 makes the
computer input a string from the file and call the string F$; so
F$ becomes the name of one of your friends. Line 40 prints that
friend's name onto your screen. Line 50 creates a loop, so that
the names of all your friends are printed on the screen.
Eventually, the computer will reach the end of the file, and
there won't be any more names to input from the file. Line 20
says: if the computer reaches the End Of the File and can't input
any more names from it, the computer should print on your screen
``THOSE ARE ALL THE FRIENDS'', then CLOSE the file and END the
program.
LOF
In the middle of your program, if you say PRINT LOF(1), the
computer will tell you the Length Of the File: it will tell you
how many bytes are in the file.
Multiple files
If you want the computer to handle two files simultaneously,
use two OPEN statements. At the end of the first OPEN statement,
say ``AS 1''; at the end of the second OPEN statement, say ``AS
2''.
For the second file, say PRINT#2 instead of PRINT#1, say
INPUT#2 instead of INPUT#1, say EOF(2) instead of EOF(1), and say
LOF(2) instead of LOF(1).
How to CLOSE
The CLOSE statement closes all files. To be more specific, you
can say CLOSE 1 (which closes just the first file) or CLOSE 2
(which closes just the second).
Whenever you're done using a file, CLOSE it immediately. When
you say CLOSE, the computer puts finishing touches on the file
that protect the file against damage.
Suppose that halfway through your program, you finish using
file 2 but want to continue using file 1. Say CLOSE 2 there, and
delay saying CLOSE 1 until later.
RANDOM ACCESS
On a disk, you can store two kinds of data files. The simple
kind is called a sequential-access data file; the complicated
kind is called a random-access (or relative-access or
direct-access) data file. You've already learned how to create
and retrieve a sequential-access file. Now let's look at
random-access.
Though more complicated than sequential-access data files,
random-access data files have an advantage: they let you skip
around. In a sequential-access data file, you must look at the
first item of data, then the second, then the third, etc. In a
random-access data file, you can look at the seventh item of
data, then skip directly to the tenth, then hop back to the
third, then skip directly to the sixth, etc.
Each item is called a record. The number of characters (bytes)
in the record is called the record's length. For example, if a
record contains 30 characters, the record's length is 30. In a
random-access file, all the records must have the same length as
each other.
PUT
Let's create a random-access file called JIM. Let's make JIM's
record length be 20, so that each record will contain 20
characters. Here's how:
5 OPEN "JIM" AS 1 LEN=20: FIELD 1, 20 AS X$
Let's make JIM's 7th record be ``LOVE MAKES ME GIGGLE'' (which
contains 20 characters):
10 LSET X$="LOVE MAKES ME GIGGLE": PUT 1,7
Let's make JIM's 9th record be ``PLEASE HOLD MY HAND'':
20 LSET X$="PLEASE HOLD MY HAND": PUT 1,9
Since JIM's record length is supposed to be 20 characters but
``PLEASE HOLD MY HAND'' contains just 19 characters, the computer
will automatically add a blank to the end of ``PLEASE HOLD MY
HAND''.
Let's make JIM's 4th record be ``I LOVE LUCY'':
30 LSET X$="I LOVE LUCY": PUT 1,4
The computer will automatically add blanks to the end of ``I LOVE
LUCY''.
To finish the program, say:
40 CLOSE
GET
This program makes the computer tell you JIM's 7th item:
5 OPEN "JIM" AS 1 LEN=20: FIELD 1, 20 AS X$
10 GET 1,7: PRINT X$
20 CLOSE
Multi-field records
If you want each record to be a pair of strings, begin like
this:
5 OPEN "JIM" AS 1 LEN=34: FIELD 1, 30 AS X$, 4 AS Y$
10 LSET X$="LOVE MAKES ME GIGGLE": LSET Y$="WOW": PUT 1,7
etc.
Line 5 makes each record
consist of two fields. The first field is a 30-character string
called X$; the second field is a 4-character string called Y$.
Line 10 says to PUT into
the 7th record this pair of strings: ``LOVE MAKES ME GIGGLE'' and
``WOW''.
LOC
While using a
random-access file, if you say PRINT LOC(1), the computer tells
you which record it just dealt with: it tells you the record
LOCation. For example, if you say ``PUT 1,7'' or ``GET 1,7'' and
then say PRINT LOC(1), the computer prints the number 7.
If you say ``PUT 1''
instead of ``PUT 1,7'', the computer will assume you mean ``PUT
1,LOC(1)+1''. If you say ``GET 1'', the computer will assume you
mean ``GET 1,LOC(1)+1''.
End of the file
The EOF function doesn't
work well for random-access files. To deal with the end of the
file, use the following trick instead.
Suppose you say LEN=34,
so that 34 bytes make a record. Since the number of bytes in the
entire file is LOF(1), and 34 bytes make a record, the number of
records in the file is LOF(1)/34. These lines print all the
records:
100 FOR I = 1 TO LOF(1)/34
110 GET 1: PRINT X$;Y$
120 NEXT
Restrictions on FIELD variables
If you put a variable
(such as X$) into a FIELD statement, you cannot put it into an
ordinary ``='' statement: instead of saying X$=``LOVE MAKES ME
GIGGLE'', you must say LSET X$=``LOVE MAKES ME GIGGLE''. You
cannot put the variable into an INPUT statement: instead of
saying INPUT X$, you must say INPUT A$ and then LSET X$=A$.
Numerical data
On most computers, a
random-access file must contain strings, not numbers. If you want
to store numbers, you must turn them into strings.
To turn an integer into
a string, use the function MKI$ (MaKe from Integer). It turns the
integer into a 2-byte string, even if the integer is long. For
example, to turn the integer 17999 into a 2-byte string called
X$, say FIELD 1, 2 AS X$ and say LSET X$=MKI$(17999).
The function MKS$ (MaKe
from Single-precision real) turns a real number into a 4-byte
string. The function MKD$ (MaKe from Double-precision) turns a
double-precision number into an 8-byte string.
Suppose you turn a
number into a string (by using MKI$, MKS$, or MKD$), and PUT the
string into a file, and later GET the string back from the file.
You'll want to convert the string back to a number. Use the
function CVI (ConVert to Integer) or CVS (ConVert to
Single-precision) or CVD (ConVert to Double-precision). For
example, if X$ is a 2-byte string that stands for an integer, you
can make the computer print the integer by saying PRINT CVI(X$).
CREATE A DATABASE
The following program creates a database, in which you can
store information about your friends & enemies, your business &
bills, birthdays & appointments, desires & dreads, and whatever
else bothers you. After storing the information in the database,
you can peek at the information, change it, expand on it, delete
it, or do whatever else strikes your fancy.
Chronological database
The program consists of a main routine and 7 subroutines:
The main routine
All variables will be integers.10 DEFINT A-Z
Allow 100 topics & their data.20 DIM T$(100),D$(100)
Number of topics starts at 0.30 N=0
Ask the human for a topic.40 PRINT: PRINT "WHAT TOPIC INTERESTS
YOU?": PRINT "(IF YOU'RE NOT SURE, TYPE A QUESTION MARK)": L
INE INPUT T$
Do what the human wishes.50 IF T$="?" THEN GOSUB 1000 ELSE GOSUB
2000
Go to another topic.60 GO TO 40
Subroutine 1000: tell the human what topics are in the database
If database is empty, say so.1000 IF N=0 THEN PRINT "I DON'T KNOW
ANY TOPICS YET.": PRINT "MY MIND IS STILL BLANK.": PRINT "PLE ASE
TEACH ME A NEW TOPIC.": RETURN
If not empty, list the topics.1010 PRINT "I KNOW ABOUT THESE
TOPICS:": FOR I = 1 TO N: PRINT T$(I),: NEXT I: PRINT: PRINT
"PICK
ONE OF THOSE TOPICS, OR TEACH ME A NEW ONE."
1020 RETURN
Subroutine 2000: search through the database, to find the topic
T$
Start searching.2000 FOR I = 1 TO N
If the topic is found, do 3000.2010 IF T$=T$(I) THEN GOSUB
3000: RETURN
If not found yet, try again.2020 NEXT
If never found, do 4000.2030 GOSUB 4000
2040 RETURN
Subroutine 3000: the topic's in the database
Tell the human about the topic.3000 PRINT "HERE'S WHAT I KNOW
ABOUT "T$":": PRINT D$(I)
Ask whether to change the info.3010 INPUT "DO YOU WANT TO CHANGE
THAT INFORMATION";A$
If the human says yes, do 5000.3020 IF A$="YES" OR A$="Y" THEN
GOSUB 5000
3030 RETURN
Subroutine 4000: the topic's not in the database
Say topic is not in database.4000 PRINT "I DON'T KNOW ANYTHING
ABOUT "T$"."
Request info about the topic.4010 PRINT: PRINT "TELL ME ABOUT
"T$: PRINT "(IF YOU DON'T WANT TO TELL ME, TYPE THE LETTER X)": L
INE INPUT D$
If human wants, insert topic.4020 IF D$<>"X" THEN GOSUB 6000
4030 RETURN
Subroutine 5000: change the info
Agree to change the info.5000 PRINT "OKAY. I'VE ERASED THAT
INFORMATION ABOUT "T$"."
Request new info.5010 PRINT: PRINT "TYPE WHAT YOU WANT ME TO KNOW
ABOUT "T$: PRINT "(IF YOU WANT ME TO FORGET "T$",
TYPE THE LETTER X)": INPUT D$
Change the info as requested.5020 IF D$="X" THEN GOSUB 7000 ELSE
D$(I)=D$
5030 RETURN
Subroutine 6000: insert the topic into the database
Increase the number of topics.6000 N=N+1
Append new topic & its data.6010 T$(N)=T$: D$(N)=D$
6020 RETURN
Subroutine 7000: delete the topic from the database
Replace that topic by topic #N.7000 T$(I)=T$(N): D$(I)=D$(N)
Decrease the number of topics.7010 N=N-1
7020 RETURN
If your computer doesn't understand DEFINT, omit line 10. If
your computer doesn't understand LINE INPUT, omit the word LINE
from lines 40 and 4010.
The program stores the topics in chronological order: if you
begin by feeding it information about SUE and then information
about CAROL, it will let T$(1) be SUE and let T$(2) be CAROL.
Alphabetical database
Instead of chronological order, you might prefer alphabetical
order.
For example, suppose you feed the computer information about
SUE then CAROL then ZELDA then ALICE then JANE. Here's what the
computer's memory would look like, in each kind of order:
Chronological orderAlphabetical order
SUE ALICE
CAROL CAROL
ZELDA JANE
ALICE SUE
JANE ZELDA
Which is better: chronological order or alphabetical order?
Chronological order lets you quickly add a new name (just add
it at the end of the list), but finding a name in the list is
slow (since the list looks disorganized). Alphabetical order lets
you find a name faster (since the list is alphabetized), but
adding a new name to the alphabetized list is slow (since the
only way to insert the new name is to make room for it by shoving
other names out of the way).
So which is better?
Chronological order is the simplest to program and the fastest
for INSERTING.
Alphabetical order is the fastest for FINDING information.
If you want to store the names in alphabetical order instead of
chronological order, just change subroutines 2000, 6000, and 7000
to these:
Subroutine 2000A: search through the database, to find the topic
T$
Create L and H. 2000 L=0: H=N+1
I is the average of L and H.2010 I=INT((L+H+1)/2)
If I=H, do 4000.2020 IF I=H THEN GOSUB 4000: RETURN
If the topic is found, do 3000.2030 IF T$=T$(I) THEN GOSUB 3000:
RETURN
Not found yet. Change H or L2040 IF T$<T$(I) THEN H=I ELSE L=I
and try again to find topic!2050 GO TO 2010
Subroutine 6000A: insert the topic into the database
Increase the number of topics.6000 N=N+1
Move other topics out of way.6010 FOR J = N TO I+1 STEP -1:
T$(J)=T$(J-1): D$(J)=D$(
J-1): NEXT
Insert new topic & its data.6020 T$(I)=T$: D$(I)=D$
6030 RETURN
Subroutine 7000A: delete the topic from the database
Decrease the number of topics.7000 N=N-1
Close gap from deleted topic.7010 FOR J = 1 TO N: T$(J)=T$(J+1):
D$(J)=D$(J+1): NEXT
7020 RETURN
Subroutine 2000A runs faster than chronological subroutine
2000, because searching through an alphabetical list is faster
than searching through a chronological list. (To search through
the alphabetical list super-quickly, subroutine 2000A uses a
trick called binary search.)
Unfortunately, subroutines 6000A (which inserts) and 7000A
(which deletes) run slower than chronological subroutines 6000
and 7000. To get the high speed of subroutine 2000A, you must
accept the slowness of subroutines 6000A and 7000A.
You've seen that chronological order is fast for inserting and
deleting but slow for searching, whereas alphabetical order is
exactly the opposite: it's fast for searching but slow for
inserting or deleting.
Tree-structured database
Instead of using chronological order or alphabetical order,
advanced programmers use a tree. Like chronological order, a tree
lets you insert and delete quickly. Like alphabetical order, a
tree lets you search quickly also.
Poets say, ``only God can make a tree.'' Does that mean
advanced programmers are God?
To learn how to make a tree, begin by sketching a picture of a
tree on paper. Since N is the alphabet's middle letter, begin by
writing the letter N, and put two arrows underneath it:
N
The left arrow is called the before-arrow; it will point to the
names that come alphabetically before N. The right arrow is
called the after-arrow; it will point to the names that come
alphabetically after N.
For example,
suppose your first topic is SUE. Since SUE comes alphabetically
after N, put SUE at the tip of N's after-arrow:
N
SUE
Suppose your
next topic is CAROL. Since CAROL comes alphabetically before N,
put CAROL at the tip of N's before-arrow:
N
CAROL SUE
Suppose your
next topic is ZELDA. Since ZELDA comes after N, we'd like to put
ZELDA at the tip of N's after-arrow; but SUE's already stolen
that position. So compare ZELDA against SUE. Since ZELDA comes
after SUE, put ZELDA at the tip of SUE's after-arrow:
N
CAROL SUE
ZELDA
Suppose your
next topic is ALICE. Since ALICE comes before N, look at the tip
of N's before-arrow. Since CAROL's stolen that position, compare
ALICE against CAROL; since ALICE comes before CAROL, put ALICE at
the tip of CAROL's before-arrow:
N
CAROL SUE
ALICE ZELDA
Suppose your
next topic is JANE. Since JANE comes before N, look at the tip of
N's before-arrow. Since CAROL's stolen that position, compare
JANE against CAROL; since JANE comes after CAROL, put JANE at the
tip of CAROL's after-arrow:
N
CAROL SUE
ALICE JANE ZELDA
If the next few topics are FRED, then LOU, then RON, then BOB,
the tree looks like this:
N
CAROL SUE
ALICE JANE RON ZELDA
BOB FRED LOU
Look at the arrows that point down from N. N's before-arrow
points to the group of names that come alphabetically before N
(such as CAROL, ALICE, JANE, BOB, FRED, and LOU); N's after-arrow
points to the group of names that come alphabetically after N
(such as SUE, RON, and ZELDA). Similarly, CAROL's before-arrow
points to the group of names that come alphabetically before
CAROL (such as ALICE and BOB); CAROL's after-arrow points to the
group of names that come alphabetically after CAROL (such as
JANE, FRED, and LOU).
Programmers treat the tree as if it were a ``family tree''.
CAROL is called the parent of ALICE and JANE, who are therefore
called CAROL's children. CAROL is called the ancestor of ALICE,
JANE, BOB, FRED, and LOU, who are therefore called CAROL's
descendants. The arrows are called pointers.
To make the tree more useful, begin with ``N !'' instead of
``N'' (so you can choose ``N'' as a topic later), and number the
topics in the order they appeared: since SUE was the first topic,
put ``1'' in front of SUE; since CAROL was the second topic, put
``2'' in front of CAROL; since ZELDA was the third topic, put
``3'' in front of ZELDA, like this:
N !
2CAROL 1SUE
4ALICE 5JANE 8RON 3ZELDA
9BOB 6FRED7LOU
To describe the tree to the computer, store this table in the
computer's memory:
Topic Where the before-arrow
pointsWhere the after-arrow points
0 N ! 2 1
1 SUE 8 3
2 CAROL 4 5
3 ZELDA 0 0
4 ALICE 0 9
5 JANE 6 7
6 FRED 0 0
7 LOU 0 0
8 RON 0 0
9 BOB 0 0
That table represents the tree and is called the tree's
representation.
The table's left column is in
chronological order, but the other columns give information about
alphabetizing. So a tree combines chronological order with
alphabetical order: it combines the advantages of both. Adding a
new topic to the tree is quick and easy (as in chronological
order): just add the name to the bottom of the list, and adjust a
few arrows. Using the tree to search for a topic is quick and
easy (as in alphabetical order): just follow the arrows.
Like the alphabetical program, the
program that creates and manipulates the tree uses the same
subroutines 1000, 3000, 4000, and 5000 as the chronological
program. To create the tree, change the main routine and
subroutines 2000, 6000, and 7000. You must also add a new
subroutine (8000). Here are those new routines:
The main routine T
All variables will be integers. 10 DEFINT A-Z
Allow 100 topics, data, etc. 20 DIM
T$(100),D$(100),P(100,2)
Topic #0 is "N !". 30 T$(0)="N !":
P(0,1)=0: P(0,2)=0
The number of real topics is 0. 40 N=0
Ask the human for a topic. 50 PRINT: PRINT "WHAT
TOPIC INTERESTS YOU?": PRINT "(I
F YOU'RE NOT SURE,
TYPE A QUESTION MARK)": LINE INPUT T$
Do what the human wishes. 60 IF T$="?" THEN
GOSUB 1000 ELSE GOSUB 2000
Go to another topic. 70 GO TO 50
Subroutine 2000T: search through the database, to find the topic
T$
Starting at 0, hunt for T$. 2000 I=0: GOSUB 8000
If absent, do 4000, else 3000. 2010 IF I=0 THEN GOSUB
4000 ELSE GOSUB 3000
2020 RETURN
Subroutine 6000T: insert the topic into the database
Increase the number of topics. 6000 N=N+1
Append new topic & its data. 6010 T$(N)=T$:
D$(N)=D$: P(N,1)=0: P(N,2)=0
Make topic I1 point to it. 6020 P(I1,J)=N
6030 RETURN
Subroutine 7000T: delete the topic from the database
Make topic I1 (which was pointing to the vanishing topic) point
to the vanishing topic's left child instead.
7000 P(I1,J)=P(I,1)
A is the number of the vanishing topic. B is the number of the
vanishing topic's right child.
7010 A=I: B=P(I,2)
If the vanishing topic has a right child, make something point to
that child.
7020 IF B>0 THEN
T$=T$(B): I=I1: GOSUB 8000: P(I1,J)=B
If the vanishing topic isn't topic N, move topic N to the gap
left by the vanishing topic.
7030 IF A<N THEN
T$=T$(N): I=0: GOSUB 8000: P(I1,J)=A:
T$(A)=T$:
D$(A)=D$(N): P(A,1)=P(N,1): P(A,2)=P(N,2)
Decrease the number of topics. 7040 N=N-1
7050 RETURN
Subroutine 8000T
Starting at position I, hunt for T$ in the database. If T$ is
missing from the database, make I be 0; otherwise make I be the
position of T$. Find the topic that points to T$. Make I1 be that
topic's position. If the arrow pointing to T$ points left, make J
be 1; otherwise make J be 2. Here's how to do all that:
If the topic is found, return. 8000 IF T$=T$(I) THEN
RETURN
Compute a tentative J. 8010 IF T$<T$(I) THEN
J=1 ELSE J=2
Compute a tentative I1 and I. 8020 I1=I: I=P(I,J)
If pointer is not 0, hunt again. 8030 IF I>0 THEN GO TO
8000
8040 RETURN
Disk-based database
All those database programs
(chronological, alphabetical, and tree) put data into the RAM.
When you turn off the power, the RAM forgets all the data!
This superior program puts the database onto a disk instead of
into RAM:
The main routine D
Prepare the variables.10 DEFINT A-Z: DIM PF$(2): Z$=MKI$(0)
Open the file and its fields.20 OPEN "INFO" AS 1 LEN=128: FIELD
1, 44 AS TF$, 80 AS DF$, 2 AS PF$(1), 2 AS PF$(2)
Topics #1 and #2 are headers. Topic #2 should be "N !", and topic
#1's left pointer should be N.
30 IF LOF(1)=0 THEN N=2: LSET TF$="N !": LSET
PF$(1)=Z$: LSET PF$(2)=Z$: PUT 1,2 ELSE GET 1,1: N=CV
I(PF$(1))
Ask the human for a topic.40 PRINT: PRINT "WHAT TOPIC INTERESTS
YOU?": PRINT "(IF YOU'RE NOT SURE, TYPE A QUESTION MARK)": PR
INT "(IF YOU WANT TO END, TYPE THE LETTER X)":
LINE INPUT T$
If the human wishes, do 1000.50 IF T$="?" THEN GOSUB 1000: GO TO
40
If the human wishes, end.60 IF T$="X" THEN LSET PF$(1)=MKI$(N):
PUT 1,1: CLOSE: END
Make TS$ resemble T$ but be 44 characters long (by adding blank
spaces at the end).
70 LSET TF$=T$: TS$=TF$
Find the topic. 80 GOSUB 2000
Go to another topic.90 GO TO 40
Subroutine 1000D: tell the human what topics are in the file
If just headers, say so.1000 IF N=2 THEN PRINT "I DON'T KNOW ANY
TOPICS YET.": PRINT "MY MIND IS STILL BLANK.": PRINT "PLEA
SE TEACH ME A NEW TOPIC.": RETURN
If file has topics, list them.1010 PRINT "I KNOW ABOUT THESE
TOPICS:": FOR I = 3 TO N: GET 1,I: PRINT TF$: NEXT: PRINT "PICK
ONE
OF THOSE TOPICS, OR TEACH ME A NEW ONE."
1020 RETURN
Subroutine 2000D: search through the file, to find the topic TS$
Starting at 2, hunt for TS$.2000 I=2: GOSUB 8000
If absent, do 4000, else 3000.2010 IF I=0 THEN GOSUB 4000 ELSE
GOSUB 3000
2020 RETURN
Subroutine 3000D: the topic's in the file
Tell the human about the topic.3000 PRINT "HERE'S WHAT I KNOW
ABOUT "T$":": PRINT DF$
Ask whether to change the info.3010 INPUT "DO YOU WANT TO CHANGE
THAT INFORMATION";A$
If the human says yes, do 5000.3020 IF A$="YES" OR A$="Y" THEN
GOSUB 5000
3030 RETURN
Subroutine 4000D: the topic's not in the file
Say topic is not in the file.4000 PRINT "I DON'T KNOW ANYTHING
ABOUT "T$"."
Request info about the topic.4010 PRINT: PRINT "TELL ME ABOUT
"T$: PRINT "(IF YOU DON'T WANT TO TELL ME, TYPE THE LETTER X)":
LI
NE INPUT D$
If human wants, insert topic.4020 IF D$<>"X" THEN GOSUB 6000
4030 RETURN
Subroutine 5000D: change the info
Agree to change the info.5000 PRINT "OKAY. I'VE ERASED THAT
INFORMATION ABOUT "T$"."
Request new info.5010 PRINT: PRINT "TYPE WHAT YOU WANT ME TO KNOW
ABOUT "T$: PRINT "(IF YOU WANT ME TO FORGET "T$",
TYPE THE LETTER X)": LINE INPUT D$
Change the info as requested.5020 IF D$="X" THEN GOSUB 7000 ELSE
LSET DF$=D$: PUT 1,I
5030 RETURN
Subroutine 6000D: insert the topic into the file
Increase the number of topics.6000 N=N+1
Let topic I1 point to topic N.6010 LSET PF$(J)=MKI$(N): PUT 1,I1
Append the new topic, at N.6020 LSET TF$=TS$: LSET DF$=D$: LSET
PF$(1)=Z$: LSET PF$(2)=Z$: PUT 1,N
6030 RETURN
Subroutine 7000D: delete the topic from the file
A is the number of the vanishing topic. P1 and P2 are the topic's
pointers.
7000 A=I: P1=CVI(PF$(1)): P2=CVI(PF$(2))
Make topic I1 (which was pointing to the vanishing topic) point
to the vanishing topic's left child instead.
7010 GET 1,I1: LSET PF$(J)=MKI$(P1): PUT 1,I1
If the vanishing topic has a right child, make something point to
that child.
7020 IF P2>0 THEN GET 1,P2: TS$=TF$: I=I1: GOSUB
8000: LSET PF$(J)=MKI$(P2): PUT 1,I1
If the vanishing topic isn't topic N, move topic N to the gap
left by the vanishing topic.
7030 IF A<N THEN GET 1,N: PUT 1,A: TS=TF$: I=2:
GOSUB 8000: GET 1,I1: LSET PF$(J)=MKI$(A): PUT 1,I1
Decrease the number of topics.7040 N=N-1
7050 RETURN
Subroutine 8000D
Starting at position I, hunt for TS$ in the file. If TS$ is
missing from the database, make I be 0; otherwise make I be the
position of TS$.
Find the topic that points to TS$. Make I1 be that topic's
position. If the arrow pointing to TS$ points left, make J be 1;
otherwise make J be 2.
Here's how to do all that:
Start at position I.8000 GET 1,I
If the topic is found, return.8010 IF TS$=TF$ THEN RETURN
Compute a tentative J.8020 IF TS$<TF$ THEN J=1 ELSE J=2
Compute a tentative I1 and I.8030 I1=I: I=CVI(PF$(J))
If pointer not 0, hunt again.8040 IF I>0 THEN GO TO 8000
8050 RETURN